package cdu.sl.aichatdemo.config;


import cdu.sl.aichatdemo.filters.JwtTokenFilter;
import cdu.sl.aichatdemo.provider.EmailCodeAuthenticationProvider;
import cdu.sl.aichatdemo.service.CustomUserService;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    @Value("${security.permit-urls}")
    private String permitUrlsStr;

    private final JwtTokenFilter jwtTokenFilter;

    private final CustomUserService userDetailsService;

    private final ObjectMapper objectMapper;

    private final EmailCodeAuthenticationProvider emailCodeAuthenticationProvider;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        String[] permitUrls = permitUrlsStr.split(",");
        http.csrf(AbstractHttpConfigurer::disable)
                .sessionManagement(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(auth ->
                        auth.requestMatchers(permitUrls).permitAll()
                                .anyRequest().authenticated())
                // 将JwtTokenFilter过滤器添加到UsernamePasswordAuthenticationFilter之前
                .addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);

        http.authenticationProvider(emailCodeAuthenticationProvider);
        return http.build();
    }


    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }


    /**
     * 配置AuthenticationManager
     */
    @Bean
    public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception {
        AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);
        // 添加自定义的认证提供者
        authenticationManagerBuilder.authenticationProvider(emailCodeAuthenticationProvider);
        // 配置其他认证方式
        authenticationManagerBuilder.userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());

        return authenticationManagerBuilder.build();
    }


//    /**
//     * 配置自定义认证过滤器
//     */
//    @Bean
//    public EmailCodeAuthenticationFilter emailCodeAuthenticationFilter(AuthenticationManager manager) throws Exception {
//        EmailCodeAuthenticationFilter filter = new EmailCodeAuthenticationFilter();
//        filter.setAuthenticationManager(manager);
//
//
//        // 设置认证成功和失败处理器
//        filter.setAuthenticationSuccessHandler((request, response, authentication) -> {
//            response.setContentType("application/json;charset=UTF-8");
//            response.getWriter().write("{\"success\": true, \"message\": \"登录成功\"}");
//        });
//
//        filter.setAuthenticationFailureHandler((request, response, exception) -> {
//            response.setStatus(HttpStatus.UNAUTHORIZED.value());
//            response.setContentType("application/json;charset=UTF-8");
//            response.getWriter().write("{\"success\": false, \"message\": \"" + exception.getMessage() + "\"}");
//        });
//
//        return filter;
//    }


}
